package zf.media
{
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.media.ID3Info;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	
	import zf.media.audio.SoundSpectrumSprite;
	import zf.media.audio.lrc.Lrc;
	import zf.media.audio.lrc.LrcEvent;

	/**
	 * 错误事件 
	 * @eventType flash.events.ErrorEvent.ERROR
	 */
	[Event(name="error", type="flash.events.ErrorEvent")]
	
	/**
	 * ID3事件，获取到MP3的ID3属性时候触发
	 * @eventType flash.events.Event.ID3
	 */
	[Event(name="id3", type="flash.events.Event")]
	
	/**
	 * 声音载入完成事件
	 * @eventType flash.events.Event.INIT
	 */
	[Event(name="init", type="flash.events.Event")]
	
	/**
	 * 载入声音事件，载入声音时连续触发，以此获取载入信息
	 * @eventType flash.events.ProgressEvent.PROGRESS
	 */
	[Event(name="progress", type="flash.events.ProgressEvent")]
	
	/**
	 * 声音播放到结尾事件
	 * @eventType flash.events.Event.COMPLETE
	 */
	[Event(name="complete", type="flash.events.Event")]
	
	/**
	 * 歌词载入完成事件
	 * @eventType lor.media.audio.lrc.LrcEvent.LRC_LOAD_COMPLETE
	 */
	[Event(name="lrc_load_complete", type="zf.media.audio.lrc.LrcEvent")]
	
	/**
	 * 歌词变化事件
	 * @eventType lor.media.audio.lrc.LrcEvent.LRC_CHANGE
	 */
	[Event(name="lrc_change", type="zf.media.audio.lrc.LrcEvent")]
	
	/**
	 * 声音控制器 
	 * @author mike.zhang
	 * 
	 */
	public class SoundControl extends EventDispatcher
	{
		private var _soundPath:String;
		private var _lrcPath:String;
		
		private var _volume:Number=1;
		private var _pan:Number=0;
		
		private var _sss:SoundSpectrumSprite;
		
		private var sd:Sound;
		private var sc:SoundChannel;
		private var lrc:Lrc;
		
		private var lrcLoaded:Boolean;
		private var soundLoaded:Boolean;
		private var id3Loaded:Boolean;
		/**
		 * 创建一个声音控制器 
		 * 
		 */
		public function SoundControl()
		{
		}	

		/**
		 * 获取声音文件地址 
		 * @return 
		 * 
		 */
		public function get soundPath():String
		{
			return _soundPath;
		}
		
		/**
		 * 获取LRC歌词文件地址 
		 * @return 
		 * 
		 */
		public function get lrcPath():String
		{
			return _lrcPath;
		}
		
		/**
		 * 获取当前MP3的ID3信息 
		 * @return ID3Info
		 * 
		 */
		public function get id3():ID3Info
		{
			if(id3Loaded)
			{
				return sd.id3; 
			}
			return null;
		}
		
		/**
		 * 音量范围从 0（静音）至 1（最大音量）。
		 * @return 
		 * 
		 */
		public function get volume ():Number
		{
			return _volume;
		}
		public function set volume (num:Number):void
		{
			if (sc)
			{
				sc.soundTransform=new SoundTransform(num,_pan);
			}
			_volume=num;
		}
		
		/**
		 * 声音从左到右的平移，范围从 -1（左侧最大平移）至 1（右侧最大平移）。
		 * @return 
		 * 
		 */
		public function get pan ():Number
		{
			return _pan;
		}
		public function set pan (num:Number):void
		{
			if (sc)
			{
				sc.soundTransform=new SoundTransform(_volume,num);
			}
			_pan=num;
		}
		
		/**
		 * 当播放声音时，position 属性指示声音文件中当前播放的位置。以毫秒为单位 
		 * @return 
		 * 
		 */
		public function get position ():Number
		{
			var num:Number;
			try
			{
				num=sc.position;
			}
			catch (e:Error)
			{
				num=0;
			}
			return num;
		}
		/**
		 * 当前声音的长度。以毫秒为单位 
		 * @return 
		 * 
		 */
		public function get length ():Number
		{
			if (soundLoaded)
			{
				return sd.length;
			}
			if (!sd)
			{
				return 0;
			}
			return sc.position * sd.bytesTotal / sd.bytesLoaded;
		}

		/**
		 * 配置 
		 * 
		 */
		private function config():void
		{
			sd=new Sound;
			sc=new SoundChannel;
			lrc=new Lrc;
			
			lrcLoaded=false;
			soundLoaded=false;
			id3Loaded=false;
		}
		/**
		 * 载入LRC歌词 
		 * 
		 */
		private function loadLrc():void
		{
			if(_lrcPath)
			{
				lrc.load(_lrcPath);
				lrc.addEventListener(LrcEvent.LRC_LOAD_COMPLETE,lrcLoadCompleteEvent);
				lrc.addEventListener(LrcEvent.LRC_CHANGE,lrcChangeEvent);
				lrc.addEventListener(ErrorEvent.ERROR,errorEvent);
			}
		}
		/**
		 * 歌词载入完成处理事件 ，将发出 LrcEvent.LRC_LOAD_COMPLETE
		 * @param e
		 * 
		 */
		private function lrcLoadCompleteEvent(e:LrcEvent):void
		{
			lrc.update(sc);
			e.stopPropagation();
			dispatchEvent(new LrcEvent(e.type,e.lyric));
		}
		/**
		 * 歌词变化事件，将发出 LrcEvent.LRC_CHANGE
		 * @param e
		 * 
		 */
		private function lrcChangeEvent(e:LrcEvent):void
		{
			e.stopPropagation();
			dispatchEvent(new LrcEvent(e.type,e.lyric));	
		}
		/**
		 * 错误处理 ，将发出 ErrorEvent.ERROR
		 * @param e 错误事件
		 * 
		 */
		private function errorEvent(e:ErrorEvent):void
		{
			//dispatchEvent(e);
		}
		/**
		 * 载入声音和歌词 
		 * @param soundPath 声音地址，必须是MP3音乐
		 * @param lrcPath LRC歌词地址
		 * 
		 */
		public function load(soundPath:String=null,lrcPath:String=null):void
		{
			if(soundPath)
			{
				_soundPath=soundPath;
			}
			if(lrcPath)
			{
				_lrcPath=lrcPath;
			}
			if(_soundPath)
			{
				config ();
				sd.load (new URLRequest(_soundPath));
				sd.addEventListener (IOErrorEvent.IO_ERROR, errorEvent);
				sd.addEventListener (Event.ID3,soundID3Event);
				sd.addEventListener (Event.COMPLETE, soundLoadCompleteEvent);
				sd.addEventListener (ProgressEvent.PROGRESS,progressEvent);
	
				if (sc.hasEventListener(Event.SOUND_COMPLETE))
				{
					sc.removeEventListener (Event.SOUND_COMPLETE,soundCompleteEvent);
				}
				
				sc=sd.play();
				loadLrc();
				
				sc.soundTransform=new SoundTransform(_volume,_pan);
			}
		}
		/**
		 * 获取MP3中ID3属性时事件 ,将发出事件Event.ID3
		 * @param e
		 * 
		 */
		private function soundID3Event(e:Event):void
		{
			id3Loaded=true;
			e.stopPropagation();
			dispatchEvent(e);
		}
		
		/**
		 * 声音载入完成事件，将发出事件Event.INIT 
		 * @param e
		 * 
		 */
		private function soundLoadCompleteEvent(e:Event):void
		{
			soundLoaded=true;
			e.stopPropagation();
			dispatchEvent(new Event(Event.INIT));
		}
		/**
		 * 声音载入进度事件，将发出事件 ProgressEvent.PROGRESS
		 * @param e
		 * 
		 */
		private function progressEvent(e:ProgressEvent):void
		{
			e.stopPropagation ();
			dispatchEvent (new ProgressEvent(ProgressEvent.PROGRESS, false, false, e.bytesLoaded, e.bytesTotal));
		}
		/**
		 * 歌曲播放到结尾事件 
		 * @param e
		 * 
		 */
		private function soundCompleteEvent(e:Event):void
		{
			e.stopPropagation();
			dispatchEvent(e);
		}
		
		/**
		 * 创建一个声音频谱精灵  
		 * @param TClass 频谱类型
		 * @param w 宽度
		 * @param h 高度
		 * @return 声音频谱精灵  
		 * @see lor.media.audio.SoundSpectrumSprite
		 */
		public function creatSoundSpectrumSprite(TClass:Class=null,w:Number=60,h:Number=40):SoundSpectrumSprite
		{
			if (_sss==null)
			{
				_sss=new SoundSpectrumSprite;
			}
			_sss.creat (w,h,TClass);
			return _sss;	
		}
		
		/**
		 * 播放控制，停止 
		 * 
		 */
		public function stop():void
		{
			if(sc)
			{
				sc.stop();
				lrc.stop();
			}
		}
		/**
		 * 播放控制，暂停 
		 * 
		 */
		public function pause ():void
		{
			if (sc)
			{
				sc.stop ();
			}
		}
		
		/**
		 * 播放控制，播放（如果前面有暂停操作，播放将从暂停点继续播放） 
		 * 
		 */
		public function play():void
		{
			if(sc)
			{
				seek(sc.position);
			}
		}
		
		/**
		 * 将播放头跳至参数time指定的毫秒处播放 
		 * @param time 时间，毫秒为单位
		 * 
		 */
		public function seek (time:int=0):void
		{
			if (sc)
			{
				if (sc.hasEventListener(Event.SOUND_COMPLETE))
				{
					sc.removeEventListener (Event.SOUND_COMPLETE,soundCompleteEvent);
				}

				sc.stop ();
				sc=sd.play(time);
				lrc.update (sc);
				sc.soundTransform=new SoundTransform(_volume,_pan);
				sc.addEventListener (Event.SOUND_COMPLETE,soundCompleteEvent);
			}
		}
	}
}